home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_200
/
299_01
/
bp.c
< prev
next >
Wrap
Text File
|
1989-12-28
|
29KB
|
863 lines
/****************************************************************************/
/* file name: bp.c */
/* (c) by Ronald Michaels. This program may be freely copied, modified, */
/* transmitted, or used for any non-commercial purpose. */
/* this is the main file of the back propagation program */
/* This program compiles under the Zortech c compiler v. 1.07 using their */
/* graphics library or under Ecosoft v4.07 (set GRAPH 0) */
/****************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include"error.h"
#include"random.h"
#define GRAPH 0 /* GRAPH 1 if it is desired to link in the graphics */
/* GRAPH 0 if no graph is desired */
#if GRAPH==1
#include"plot.h"
#endif
#ifdef ECO
#include<malloc.h> /* required for eco-c compiler */
#endif
#define U(x) (unsigned int)(x) /* type conversion */
#define SQ(x) ((x)*(x)) /* square macro */
/* function prototypes */
void getdata (FILE *bp1,FILE *bp2);
void getpattern (FILE *bp1,int,int,double *);
void allocate_memory (void);
void init_weights (int,int,double *);
void learn (int);
void foreward (int,int,double *,double *,double *);
void recognise (void);
void calc_delta_o (int,int,double *,double *,double *);
void calc_delta_h (int,int,double *,double *,double *,double *);
void calc_descent (int,int,double,double,double *,double *,double *);
void correct_weight (int,int,double *,double *);
double activate (double);
double pattern_error (int,int,double *,double *);
void print_scale (void);
void get_seed(void);
void get_limits(void);
void dump (int); /* function to dump intermediate results */
/* external variable declarations */
double *input; /* pointer to input matrix */
double *output; /* pointer to output unit output vector */
double *target; /* pointer to target matrix */
double *weight_h; /* pointer to weight matrix to hidden units */
double *weight_o; /* pointer to weight matrix to output units */
double *hidden; /* pointer to hidden unit output vector */
double *delta_o; /* pointer to output unit delta vector */
double *delta_h; /* pointer to hidden unit delta vector */
double *descent_h; /* pointer to weight change matrix for weights to
hidden units */
double *descent_o; /* pointer to weight change matrix for weights to
output units */
int n_pattern; /* number of training patterns to be used */
int n_input; /* number of input units in one pattern (dimensionality) */
int n_hidden; /* number of hidden units */
int n_output; /* number of output units in one target (dimensionality) */
double learning_rate; /* learning rate parameter */
double momentum; /* proportion of previous weight change */
FILE *bp3; /* pointer to output file bp3.dat */
/****************************************************************************/
int main() /* some compilers want main to be void */
{
FILE *bp1; /* pointer to input file bp1.dat */
FILE *bp2; /* pointer to input file bp2.dat */
char buff[10]; /* buffer to hold number of cycles */
int choice; /* program control choice */
int p; /* pattern counter */
int cycles; /* number of cycles for learning algorithm */
if((bp1=fopen("bp1.dat","r"))==NULL){ /* open data input file */
error(0,FATAL);
}
if((bp2=fopen("bp2.dat","r"))==NULL){ /* open configuration file */
error(1,FATAL);
}
if((bp3=fopen("bp3.dat","w"))==NULL){ /* open output file */
error(2,FATAL);
}
/* get training pattern size from input file bp1.dat */
getdata(bp1,bp2);
/* allocate space for input vectors */
allocate_memory();
/* load input patterns into memory */
getpattern(bp1,n_pattern,n_input,input);
/* load target patterns into memory */
getpattern(bp1,n_pattern,n_output,target);
get_seed(); /* seed random number generator */
get_limits(); /* set range of random numbers */
/* initialise weight matrices with random weights */
init_weights(n_input,n_hidden,weight_h);
init_weights(n_hidden,n_output,weight_o);
/* enter program control loop */
for(;;){
printf("\nBack Propagation Generalised Delta Rule Learning Program\n");
printf(" Learn\n Recognise\n");
printf(" Dump\n Quit\n");
printf("choice:");
choice = getch();
putchar(choice);
switch(choice){
case 'l':
case 'L':
printf("\nHow Many Cycles?\n");
cycles=atoi(gets(buff));
if(cycles<1)cycles=1;
learn(cycles);
break;
case 'r':
case 'R':
recognise();
break;
case 'd':
case 'D':
for(p=0;p<n_pattern;p++)dump(p);
printf("\nNetwork variables dumped into file bp3.dat");
break;
case 'q':
case 'Q':
exit(0);
default:
break;
}
}
fclose(bp1);
fclose(bp2);
fclose(bp3);
}
/****************************************************************************/
/* getdata */
/* this function gets data from the data file regarding the size and number */
/* of patterns and the configuration file */
/****************************************************************************/
void getdata(
FILE *bp1, /* pointer to input file bp1.dat */
FILE *bp2 /* pointer to input file bp2.dat */
)
{
if(fscanf(bp1,"%d",&n_pattern)==EOF){ /* get the number */
error(3,FATAL); /* of pattern vectors */
}
if(fscanf(bp1,"%d",&n_input)==EOF){ /* get the dimensionality */
error(3,FATAL); /* of input vectors */
}
if(fscanf(bp1,"%d",&n_output)==EOF){ /* get the dimensionality */
error(3,FATAL); /* of target vectors */
}
if(fscanf(bp1,"%d",&n_hidden)==EOF){ /* get the number */
error(3,FATAL); /* of hidden units */
}
if(fscanf(bp2,"%lf",&learning_rate)==EOF){ /* get learning rate */
error(4,FATAL);
}
if(fscanf(bp2,"%lf",&momentum)==EOF){ /* get learning momoentum */
error(4,FATAL);
}
}
/****************************************************************************/
/* allocate_memory */
/* this function allocates memory for the network */
/****************************************************************************/
void allocate_memory()
{
/* allocate space for input vectors */
if((input=(double *)calloc(U(n_pattern*n_input),sizeof(double)))==NULL){
error(6,FATAL);
}
/* allocate space for target vectors */
if((target=(double *)calloc(U(n_pattern*n_output),sizeof(double)))==NULL){
error(6,FATAL);
}
/* allocate space for output vectors */
if((output=(double *)calloc(U(n_pattern*n_output),sizeof(double)))==NULL){
error(6,FATAL);
}
/* allocate space for hidden unit vector */
if((hidden=(double *)calloc(U(n_hidden),sizeof(double)))==NULL){
error(6,FATAL);
}
/* allocate space for hidden unit delta vector */
if((delta_h=(double *)calloc(U(n_hidden),sizeof(double)))==NULL){
error(6,FATAL);
}
/* allocate space for output unit delta vector */
if((delta_o=(double *)calloc(U(n_output),sizeof(double)))==NULL){
error(6,FATAL);
}
/* allocate space for hidden weights */
if((weight_h=(double *